home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Library
/
RoseWare - Network Support Library.iso
/
apidev
/
chat.arc
/
SUPPORT.C
< prev
Wrap
C/C++ Source or Header
|
1989-03-22
|
10KB
|
431 lines
/******************************************************************************
*
* Program Name: TALK_TO.ME
*
* Filename: SUPPORT.C -- 10/25/88 4:00
*
* Purpose: Support routines for the TALK_TO.ME program
*
******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <nit.h>
#include <ctype.h>
#include "chat.h"
ECB sendECB[NUM_SEND_ECBS], *ECBqueue[NUM_RECEIVE_ECBS];
SPXHeader sendHeader[NUM_SEND_ECBS];
WORD SPXConnectionNumber, Socket = SESSION_SOCKET, connectionID,
preferredConnectionID = 0, listeningConnection;
BYTE immediateAddress[6], connectionInfo[44], networkNumber[4];
char outChar[NUM_SEND_ECBS], character,
hello[] = " wants to CHAT. To answer, type HELLO ";
int RECEIVE_FLAG = FALSE, ACTIVE_CONNECTION = 1;
extern int sendRow, sendCol, receiveRow, receiveCol;
NETWORK_NODE destNode, callNode;
void SetUpSendECB();
void SetUpReceiveECBs();
void SendPacket();
void TearDownConnection();
ECB *SetUpInitialECB();
void SendMessage();
void PrintCharacter();
int PollForMessage();
void ListenESR();
extern ESRHandler();
extern void Update();
extern void ScrollUp();
extern void SetCursor();
extern DeleteChar();
ECB *SetUpInitialECB()
{
static ECB initialECB;
static SPXHeader initialHeader;
unsigned transportTime;
BYTE immediateAddress[6];
GetInternetAddress (listeningConnection, networkNumber, (BYTE *)&destNode);
/* Put the destination header in the address */
memcpy(initialHeader.destinationNetwork, networkNumber, 4);
memcpy(initialHeader.destinationNode, &destNode, 6);
memcpy(&initialHeader.destinationSocket, &Socket, 2);
initialHeader.packetType = 5;
initialHeader.length = IntSwap(sizeof(SPXHeader));
/* Now initialzie your initial ECB */
initialECB.socketNumber = Socket;
initialECB.inUseFlag = 0;
initialECB.ESRAddress = 0; /* no event service routine, just poll */
initialECB.fragmentCount = 1;
initialECB.fragmentDescriptor[0].address = &initialHeader;
initialECB.fragmentDescriptor[0].size = sizeof(initialHeader);
return( (ECB *)&initialECB );
}
void SetUpReceiveECBs()
{
int i;
char *inChar;
ECB *receiveECB;
SPXHeader *receiveHeader;
for ( i = 0; i < NUM_RECEIVE_ECBS; i++ )
{
if( (receiveECB = (ECB *)calloc(1,sizeof(ECB)) ) == (ECB *)NULL )
Error("Out of memory during packet allocation",0);
if( (receiveHeader = (SPXHeader *)calloc(1,sizeof(SPXHeader)) ) == (ECB *)NULL)
Error("Out of memory during packet allocation",0);
if ( (inChar = (char *)calloc(1,sizeof(char)) ) == (ECB *)NULL)
Error("Out of memory during packet allocation",0);
receiveHeader->packetType = (char)5;
receiveHeader->length = IntSwap(sizeof(SPXHeader));
receiveECB->ESRAddress = (void far *)ESRHandler;
receiveECB->socketNumber = Socket;
memcpy(receiveECB->immediateAddress, &destNode, 6);
receiveECB->fragmentCount = 2;
receiveECB->fragmentDescriptor[0].address = receiveHeader;
receiveECB->fragmentDescriptor[0].size = sizeof(SPXHeader);
receiveECB->fragmentDescriptor[1].address = inChar;
receiveECB->fragmentDescriptor[1].size = sizeof(char);
SPXListenForSequencedPacket (receiveECB);
}
}
void SetUpSendECB()
{
int i;
for (i = 0; i < NUM_SEND_ECBS; i++)
{
/* Fill in your address */
IPXGetInternetworkAddress(sendHeader[i].sourceNetwork); /* includes the source node */
memcpy( &sendHeader[i].sourceSocket, &Socket, 2);
/* Fill in the destination address */
memcpy(sendHeader[i].destinationNetwork, networkNumber, 4);
memcpy(sendHeader[i].destinationNode, &destNode, 6);
memcpy(&sendHeader[i].destinationSocket, &Socket, 2);
sendHeader[i].length = IntSwap(sizeof(SPXHeader));
sendHeader[i].packetType = 5;
/* Now initialize the Send ECBs */
sendECB[i].ESRAddress = 0; /* no routine, just polling */
sendECB[i].inUseFlag = 0;
sendECB[i].fragmentCount = 2;
sendECB[i].socketNumber = Socket;
memcpy(sendECB[i].immediateAddress, &destNode, 6);
sendECB[i].fragmentDescriptor[0].address = (sendHeader + i);
sendECB[i].fragmentDescriptor[0].size = sizeof(SPXHeader);
sendECB[i].fragmentDescriptor[1].address = (outChar + i);
sendECB[i].fragmentDescriptor[1].size = sizeof(char);
}
}
int PollForPacket()
{
BYTE dataType;
char ch, *charPtr;
static int out;
if (RECEIVE_FLAG > 0)
{
/* Set the queue pointer */
if (++out >= 20)
out = 0;
/* Get the data type */
dataType = (BYTE)( ((SPXHeader *)ECBqueue[out]->fragmentDescriptor[0].address)->dataStreamType);
if (dataType == TERMINATING_PACKET )
{
Update("Connection has been terminated");
return(0);
}
/* Get the character */
charPtr = (char *)(ECBqueue[out]->fragmentDescriptor[1].address);
memcpy (&character, charPtr, 1);
/* Release the ECB and print the character */
SPXListenForSequencedPacket (ECBqueue[out]);
--RECEIVE_FLAG;
PrintCharacter();
}
return(1);
}
void PrintCharacter()
{
int i;
char ch;
CursorOff();
switch (character)
{
case TAB:
ClearReceiveBox();
break;
case ENTER:
receiveRow++;
if (receiveRow > LAST_RECEIVE_ROW)
{
receiveRow = LAST_RECEIVE_ROW;
ScrollUp (1, TOP_RECEIVE_ROW, LAST_RECEIVE_ROW, FIRST_TEXT_COL, LAST_TEXT_COL);
}
receiveCol = FIRST_TEXT_COL;
break;
case BACKSPACE:
if (receiveCol > FIRST_TEXT_COL)
DeleteChar (&receiveCol, &receiveRow);
break;
default:
if (receiveCol >= LAST_TEXT_COL)
{
receiveCol = FIRST_TEXT_COL;
receiveRow++;
}
if (receiveRow > LAST_RECEIVE_ROW)
{
receiveRow = LAST_RECEIVE_ROW;
ScrollUp(1,TOP_RECEIVE_ROW,LAST_RECEIVE_ROW,FIRST_TEXT_COL,LAST_TEXT_COL);
}
SetCursor(receiveRow, receiveCol++);
putchar(character);
break;
}
SetCursor(sendRow, sendCol);
CursorOn();
}
void ListenESR(receiveECBptr)
ECB *receiveECBptr;
{
SPXHeader *header;
static int in;
if (++in >= 20)
in = 0;
ECBqueue[in] = receiveECBptr;
++RECEIVE_FLAG;
return;
}
void SendPacket(charBuffer)
char *charBuffer;
{
int ccode = 0, i;
i = FindECB();
/* Check for a valid connection */
ccode = SPXGetConnectionStatus(SPXConnectionNumber, connectionInfo);
if (ccode)
Error("Invalid connection.");
/* Send character */
memcpy( (outChar + i), charBuffer, 1);
SPXSendSequencedPacket (SPXConnectionNumber, (sendECB + i) );
if(sendECB[i].completionCode != 0)
ACTIVE_CONNECTION = 0;
else
Update ("Connection is active.");
}
void TearDownConnection()
{
int i;
i = FindECB();
sendECB[i].ESRAddress = 0;
sendECB[i].fragmentCount = 1;
sendECB[i].fragmentDescriptor[0].size = 42;
SPXTerminateConnection( SPXConnectionNumber, (sendECB + i) );
/* Wait until the Terminate has completed */
while ( sendECB[i].inUseFlag )
/* wait */;
IPXCloseSocket(Socket);
ClearScreen();
}
FindECB()
{
int ALL_ECBS_ARE_BUSY = 1, ECBnumber;
while (ALL_ECBS_ARE_BUSY)
{
for (ECBnumber = 0; ECBnumber < NUM_SEND_ECBS; ECBnumber++)
{
if (!sendECB[ECBnumber].inUseFlag)
{
ALL_ECBS_ARE_BUSY = FALSE;
break;
}
else if (ECBnumber == (NUM_SEND_ECBS - 1) )
Update ("Your partner has suspended the connection. Please wait.");
}
}
return (ECBnumber);
}
ParseDestination(server, user, command)
char *server, *user, *command;
{
int ch, i = 0, j = 0;
while ( (ch = *(command + i)) != '/' )
{
ch = toupper (ch);
*(server + i++) = (char)ch;
if (ch == '\0')
{
printf ("CHAT.EXE v1.01\n");
printf ("by Novell Technical Documentation\n\n");
printf ("Format: Chat fileserver/username\n");
printf ("Example: Chat Server_1/Rasputin\n");
exit ();
}
}
*(server + i++) = '\0';
while( (ch = *(command + i++)) != '\0' )
{
ch = toupper(ch);
*(user + j++) = (char)ch;
}
*(user + j) = '\0';
}
CheckServer(originalServer, preferredServer)
char *originalServer, *preferredServer;
{
char key;
int ccode;
connectionID = GetPreferredConnectionID();
GetFileServerName(connectionID, originalServer);
if( (strcmp(originalServer, preferredServer)) != 0 )
{
ccode = GetConnectionID(preferredServer, &preferredConnectionID);
if (ccode)
{
Error("You're not attached to that file server.");
}
SetPreferredConnectionID(preferredConnectionID);
}
}
GetConnectionAndNode(preferredServer, userName, connection)
char *preferredServer, *userName;
WORD *connection;
{
WORD *count, max = 100;
int ccode;
char networkNumber[4];
BYTE address[6];
/* Get the connection number of listening side */
ccode = GetObjectConnectionNumbers(userName, OT_USER, count,
connection, max);
/* Get the node address of the listening side */
GetInternetAddress( *(connection), networkNumber, (char *)&destNode);
/* destNode.hiNode = IntSwap(destNode.hiNode);
destNode.loNode = LongSwap(destNode.loNode); */
}
SayHello(listeningConnection)
WORD *listeningConnection;
{
BYTE result[2], time[7], address[6];
WORD callingConnection;
char callerName[48], networkNumber[4], connString[3];
int type, ccode;
long IDNumber;
/* Get connection number of calling side */
callingConnection = GetConnectionNumber();
/* Use the connection number to get the name of the caller */
GetConnectionInformation(callingConnection, callerName, &type,
&IDNumber, time);
/* Create broadcast message */
ConvertToString(&callingConnection, connString, 1);
strncat(callerName, hello, sizeof(hello) );
strncat(callerName, connString, sizeof(connString));
ccode = SendBroadcastMessage(callerName, listeningConnection, result, 1);
return( *(result) );
}
ConvertToString(number, string, size)
char *number,*string,size;
{
char i, j, k;
int left = 1;
for (i = j = k = 0; i < size; i++)
{
if (left)
{
j = *(number + i--);
j = j & 0x00F0;
j = j >> 4;
left--;
}
else
{
j = *(number + i);
j = j & 0x000F;
left++;
}
if (j < 10)
*(string + k++) = j + 0x30;
else
*(string + k++) = j + 0x37;
}
*(string + k) = '\0';
}